/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//		File Name		:		CSaveOrLoadState.cpp
//
//		Author			:		Kevin Jordan
//
//		Purpose			:		Encapsulate all functionality of the SaveOrLoadState
//
//		Dates			:		Written( Feb 17, 2011 ) by Kevin Jordan		LastUpdate( Feb 17, 2011  ) by Kevin Jordan 
//	
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "CSaveOrLoadState.h"
#include "CPlayerProfile.h"
#include "CMainMenuState.h"
#include "CGame.h"
#include "SGD Wrappers/CSGD_DirectInput.h"
#include "SGD Wrappers/CSGD_Direct3D.h"
#include "SGD Wrappers/CSGD_TextureManager.h"
#include <iostream>
#include <fstream>
#include "VIN_BitMapFont.h"
#include "CHubState.h"
#include "VIN_SoundManager.h"
using namespace std;

struct SaveData
{
	int Combat;
	int Durability;
	int Speed;
	int Rage;
	int Cash;
};

CSaveOrLoadState::CSaveOrLoadState()
{
	SaveSlot[0].SetCombat(0);
	SaveSlot[0].SetDurability(0);
	SaveSlot[0].SetHealth(0);
	SaveSlot[0].SetRage(0);
	SaveSlot[0].SetSpeed(0);
	SaveSlot[0].SetCash(0);

	SaveSlot[1].SetCombat(0);
	SaveSlot[1].SetDurability(0);
	SaveSlot[1].SetHealth(0);
	SaveSlot[1].SetRage(0);
	SaveSlot[1].SetSpeed(0);
	SaveSlot[1].SetCash(0);

	SaveSlot[2].SetCombat(0);
	SaveSlot[2].SetDurability(0);
	SaveSlot[2].SetHealth(0);
	SaveSlot[2].SetRage(0);
	SaveSlot[2].SetSpeed(0);
	SaveSlot[2].SetCash(0);

	ImageID = -1;
	m_nSelectionMenu = 0;
	m_nSelection = 0;
	m_bIsLoading = false;
	m_bIsSaving = false;
	m_bUpdate = false;
}


CSaveOrLoadState::~CSaveOrLoadState()
{

}

void CSaveOrLoadState::Enter()
{
	ReadIn(0);
	ReadIn(1);
	ReadIn(2);
	ImageID = CSGD_TextureManager::GetInstance()->LoadTexture("resource/Graphics/Rio.png");
}


void CSaveOrLoadState::Exit()
{
	m_nSelectionMenu = 0;
	m_bIsLoading = false;
	m_bIsSaving = false;
}

void CSaveOrLoadState::Render()
{
	CSGD_Direct3D* pD3D = CSGD_Direct3D::GetInstance();
	VIN_BitMapFont* pBF = VIN_BitMapFont::GetInstance();
	CSGD_TextureManager* pTM = CSGD_TextureManager::GetInstance();

	pD3D->Clear(0,0,128);

	CSGD_TextureManager::GetInstance()->Draw(ImageID, 0,0 );

	if( m_bIsSaving )
	{
		
		RECT MenuRect;
		SetRect( &MenuRect, 175, 100, 600, 500 );

		RECT MenuRectII;
		SetRect( &MenuRectII, 160, 85, 615, 515 );
		
		RECT SelectionRect;
		SetRect( &SelectionRect, 250, 110, 500, 200  );
		
		if( m_nSelection == 1 )
		{
			SetRect( &SelectionRect, 250, 235, 500, 325 );
		}
		else if( m_nSelection == 2 )
		{
			SetRect( &SelectionRect, 250, 360, 500, 450 );
		}
		
		pD3D->GetSprite()->Flush();
		pD3D->DrawRect( MenuRectII, 255,255,255);
		pD3D->DrawRect( MenuRect, 0,0,0);
		pD3D->DrawRect( SelectionRect, 0,255,0);

		char bufferSlot1[100];
		sprintf_s( bufferSlot1, sizeof(bufferSlot1), "Cash : %d", SaveSlot[0].GetCash() );
		char bufferSlot2[100];
		sprintf_s( bufferSlot2, sizeof(bufferSlot2), "Cash : %d", SaveSlot[1].GetCash() );
		char bufferSlot3[100];
		sprintf_s( bufferSlot3, sizeof(bufferSlot3), "Cash : %d", SaveSlot[2].GetCash() );

		pBF->Render( "Profile 1", 300, 125, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot1, 300, 175, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( "Profile 2", 300, 250, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot2, 300, 300, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( "Profile 3", 300, 375, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot3, 300, 425, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
	}

	if( m_bIsLoading )
	{
		RECT MenuRect;
		SetRect( &MenuRect, 175, 100, 600, 500 );

		RECT MenuRectII;
		SetRect( &MenuRectII, 160, 85, 615, 515 );
		
		RECT SelectionRect;
		SetRect( &SelectionRect, 250, 110, 500, 200  );
		
		if( m_nSelection == 1 )
		{
			SetRect( &SelectionRect, 250, 235, 500, 325 );
		}
		else if( m_nSelection == 2 )
		{
			SetRect( &SelectionRect, 250, 360, 500, 450 );
		}
		

		pD3D->GetSprite()->Flush();
		pD3D->DrawRect( MenuRectII, 255,255,255);
		pD3D->DrawRect( MenuRect, 0,0,0);
		pD3D->DrawRect( SelectionRect, 0,255,0);

		char bufferSlot1[100];
		sprintf_s( bufferSlot1, sizeof(bufferSlot1), "Cash : %d", SaveSlot[0].GetCash() );
		char bufferSlot2[100];
		sprintf_s( bufferSlot2, sizeof(bufferSlot2), "Cash : %d", SaveSlot[1].GetCash() );
		char bufferSlot3[100];
		sprintf_s( bufferSlot3, sizeof(bufferSlot3), "Cash : %d", SaveSlot[2].GetCash() );

		pBF->Render( "Profile 1", 300, 125, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot1, 300, 175, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( "Profile 2", 300, 250, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot2, 300, 300, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( "Profile 3", 300, 375, 1.0f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
		pBF->Render( bufferSlot3, 300, 425, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT );
	}

	if( !m_bIsSaving && !m_bIsLoading )
	{
		RECT MenuRect;
		SetRect( &MenuRect, 275, 100, 600, 300 );

		RECT MenuRectII;
		SetRect( &MenuRectII, 260, 85, 615, 315 );

		pD3D->GetSprite()->Flush();
		pD3D->DrawRect( MenuRectII, 255,255,255);
		pD3D->DrawRect( MenuRect, 0,0,0);

		pBF->Render( "SAVE", 400,150, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT);
		pBF->Render( "LOAD", 400,200, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT);
		pBF->Render( "EXIT", 400,250, .75f, D3DCOLOR_ARGB(255,255,0,0), MENUFONT);


		switch(m_nSelectionMenu)
		{
		case 0:
			{
				pTM->Draw(CMainMenuState::GetInstance()->GetCursorID(), 350,150, 2.0f, 1.0, 0, 0, 0 ,0, D3DCOLOR_ARGB(255,255,0,0));
				//pBF->Render( "-->", 300,150, 1.0f, D3DCOLOR_ARGB(255,255,0,0), GAMEFONT);
			}
			break;
		case 1:
			{
				pTM->Draw(CMainMenuState::GetInstance()->GetCursorID(), 350,200, 2.0f, 1.0, 0, 0, 0 ,0, D3DCOLOR_ARGB(255,255,0,0));
				//pBF->Render( "-->", 300,200, 1.0f, D3DCOLOR_ARGB(255,255,0,0), GAMEFONT);
			}
			break;
		case 2:
			{
				pTM->Draw(CMainMenuState::GetInstance()->GetCursorID(), 350,250, 2.0f, 1.0, 0, 0, 0 ,0, D3DCOLOR_ARGB(255,255,0,0));
				//pBF->Render( "-->", 300, 250, 1.0f, D3DCOLOR_ARGB(255,255,0,0), GAMEFONT);
			}
			break;
		}
	}
}


bool CSaveOrLoadState::Input()
{
	////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////
	///////LOADING
	////////////////////////////////////////////////////////////////////////
	if( m_bIsLoading)
	{		
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP))
			{
				m_nSelection--;
				if( m_nSelection < 0 )
				{
					m_nSelection = 2;
				}
			}

			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN))
			{
				m_nSelection++;
				if( m_nSelection > 2 )
				{
					m_nSelection = 0;
				}
			}
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_ESCAPE))
			{
				m_bIsLoading = false;
			}

			if( CSGD_DirectInput::GetInstance()->KeyPressed( DIK_RETURN ))
			{
				switch( m_nSelection )
				{
					
				case 0:
					{
						ReadIn(0);
						CommitToPlayer(0);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );
					}
					break;
				case 1:
					{
						ReadIn(1);
						CommitToPlayer(1);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );
					}
					break;
				case 2:
					{
						ReadIn(2);
						CommitToPlayer(2);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );
					}
					break;
				}
			}
	}

		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		///////SAVING
		////////////////////////////////////////////////////////////////////////
		else if( m_bIsSaving )
		{

			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP))
			{
				m_nSelection--;
				if( m_nSelection < 0 )
				{
					m_nSelection = 2;
				}
			}

			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN))
			{
				m_nSelection++;
				if( m_nSelection > 2 )
				{
					m_nSelection = 0;
				}
			}
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_ESCAPE))
			{
				m_bIsSaving = false;
			}

			if( CSGD_DirectInput::GetInstance()->KeyPressed( DIK_RETURN ))
			{
				switch( m_nSelection )
				{
					
				case 0:
					{
						WriteOut(0);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );

					}
					break;
				case 1:
					{
						WriteOut(1);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );

					}
					break;
				case 2:
					{
						WriteOut(2);
						VIN_SoundManager::GetInstance()->PlayMenuSelect();
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );

					}
					break;
				}
			}
		}

		/////////////////////////////////////////////////////////////////////////////////

		////////////////////////////////////////////////////////////////////////
		////////////////////////////////////////////////////////////////////////
		///////Menu
		////////////////////////////////////////////////////////////////////////
		else if( !m_bIsSaving || !m_bIsLoading )
		{
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_UP))
			{
				m_nSelectionMenu--;
				if( m_nSelectionMenu < 0 )
				{
					m_nSelectionMenu = 2;
				}
			}
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_DOWN))
			{
				m_nSelectionMenu++;
				if( m_nSelectionMenu > 2 )
				{
					m_nSelectionMenu = 0;
				}
			}
			if( CSGD_DirectInput::GetInstance()->KeyPressed(DIK_RETURN))
			{
				switch( m_nSelectionMenu )
				{
				case 0:
					{
						m_bIsSaving = true;
					}
					break;
				case 1:
					{
						m_bIsLoading = true;
					}
					break;
				case 2:
					{
						CGame::GetInstance()->ChangeState( CHubState::GetInstance() );
					}
					break;
				}
			}

		}

		return true;
}

CSaveOrLoadState* CSaveOrLoadState::GetInstance()
{
	static CSaveOrLoadState instance;
	return &instance;
}


void CSaveOrLoadState::Update( float fElapsedTIme )
{

	ReadIn(0);
	ReadIn(1);
	ReadIn(2);

}


void CSaveOrLoadState::WriteOut( int SlotToSave )
{
	if( SlotToSave < 0 || SlotToSave > 2 )
		return;
	CHubState* pHUB = CHubState::GetInstance();

	SaveData info;

	info.Combat = pHUB->GetPlayer()->GetCombat();
	info.Durability = pHUB->GetPlayer()->GetDurability();
	info.Speed = pHUB->GetPlayer()->GetSpeed();
	info.Rage = pHUB->GetPlayer()->GetRage();
	info.Cash = pHUB->GetPlayer()->GetCash();

	if( SlotToSave == 0 )
	{
		std::ofstream out("Saves/SaveFile0.dat",ios_base::out | ios_base::binary);
		if( out.is_open() )
		{
			out.write((char *)(&info), sizeof( SaveData) );

			out.close();
			out.clear();

		}
	}

	else if( SlotToSave == 1 )
	{
		std::ofstream out("Saves/SaveFile1.dat",ios_base::out | ios_base::binary);
		if( out.is_open() )
		{
			out.write((char *)(&info), sizeof( SaveData) );

			out.close();
			out.clear();

		}
	}

	if( SlotToSave == 2)
	{
		std::ofstream out("Saves/SaveFile2.dat",ios_base::out | ios_base::binary);
		if( out.is_open() )
		{
			out.write((char *)(&info), sizeof( SaveData) );

			out.close();
			out.clear();

		}
	}
}


void CSaveOrLoadState::ReadIn( int SlotToLoad )
{
	SaveData Load;

	if( SlotToLoad == 0 )
	{
		std::ifstream in("Saves/SaveFile0.dat",ios_base::in | ios_base::binary);
		if( in.is_open() )
		{
			in.read( (char*)&Load , sizeof(SaveData) );

		}

	}

	else if( SlotToLoad == 1 )
	{
		std::ifstream in("Saves/SaveFile1.dat",ios_base::in | ios_base::binary);
		if( in.is_open() )
		{
			in.read( (char*)&Load , sizeof(SaveData) );

		}
	}

	else if( SlotToLoad == 2 )
	{
		std::ifstream in("Saves/SaveFile2.dat",ios_base::in | ios_base::binary);
		if( in.is_open() )
		{
			in.read( (char*)&Load , sizeof(SaveData) );

		}
	}

	SaveSlot[SlotToLoad].SetCombat( Load.Combat );
	SaveSlot[SlotToLoad].SetDurability( Load.Durability );
	SaveSlot[SlotToLoad].SetRage( Load.Rage );
	SaveSlot[SlotToLoad].SetSpeed( Load.Speed );
	SaveSlot[SlotToLoad].SetCash( Load.Cash );

	
}

void CSaveOrLoadState::CommitToPlayer(int SlotToLoad )
{
	CHubState::GetInstance()->GetPlayer()->SetCash( SaveSlot[SlotToLoad].GetCash() );
	CHubState::GetInstance()->GetPlayer()->SetSpeed( SaveSlot[SlotToLoad].GetSpeed() );
	CHubState::GetInstance()->GetPlayer()->SetRage( SaveSlot[SlotToLoad].GetRage() );
	CHubState::GetInstance()->GetPlayer()->SetDurability( SaveSlot[SlotToLoad].GetDurability() );
	CHubState::GetInstance()->GetPlayer()->SetCombat( SaveSlot[SlotToLoad].GetCombat() );
}